package com.soxing.braindata.service.stat;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.soxing.braindata.dao.domain.request.ResearchSearchRequest;
import com.soxing.braindata.dao.domain.vo.TinyResearch;
import com.soxing.braindata.dao.entity.*;
import com.soxing.braindata.dao.service.*;
import com.soxing.braindata.domain.stat.FinishEntity;
import com.soxing.braindata.domain.vo.VpInfoVo;
import com.soxing.braindata.service.manager.IResearchManager;
import com.soxing.common.utils.response.MyPage;
import com.soxing.common.utils.response.WebResponse;
import com.soxing.common.utils.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.Map.Entry;


@Slf4j
@Service("testeeFinishImpl")
public class TesteeFinishImpl implements IStatService{

    @Resource
    private IResearchManager researchManager;

    @Resource
    private IResearchService researchService;

    @Resource
    private ITesteeExperimentService testeeExperimentService;

    @Resource
    private ITesteeService testeeService;


    @Resource
    private IExperimentService experimentService;

    @Override
    public void stat(Date beginTime, Date endTime, Integer period) {
        ResearchSearchRequest request = new ResearchSearchRequest();
        List<Integer> stateList = Lists.newArrayList();
        stateList.add(1);
        stateList.add(3);
        request.setStateList(stateList);
        request.setPageSize(10000);
        WebResponse<MyPage<TinyResearch>> response = researchManager.search(request);
        List<TinyResearch> records = response.getData().getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return;
        }
        Set<String> subjectPkIdSet = records.stream().map(TinyResearch::getSubjectPkId).collect(Collectors.toSet());
        List<Experiment> ExperimentList = experimentService.list(new LambdaQueryWrapper<Experiment>().in(Experiment::getSubjectPkId, subjectPkIdSet));
        if (CollectionUtils.isEmpty(ExperimentList)) {
            return;
        }
        Map<String,Long> ExperimentMap = ExperimentList.stream().collect(Collectors.groupingBy(Experiment::getSubjectPkId,Collectors.counting()));

        //这里主要就是遍历被试列表呀
        List<Testee> testeeList = testeeService.list(new LambdaQueryWrapper<Testee>().in(Testee::getSubjectPkId, subjectPkIdSet).in(Testee::isSign,false));
        if (CollectionUtils.isEmpty(testeeList)) {
            return;
        }

        Map<String, List<Testee>> subjectPkId2TesteeListMap = new HashMap<>();
        for (Testee testee : testeeList) {
            String subjectPkId = testee.getSubjectPkId();
            List<Testee> testeeList1 = subjectPkId2TesteeListMap.get(subjectPkId);
            if (testeeList1 == null) {
                testeeList1 = new ArrayList<>();
                subjectPkId2TesteeListMap.put(subjectPkId, testeeList1);
            }
            testeeList1.add(testee);
        }

        subjectPkId2TesteeListMap.forEach((rcode, tList) -> {
            if(!ExperimentMap.containsKey(rcode))
            {
                return;//在foreach中return相当于continue;
            }

            List<VpInfoVo> vpList = null;
            for(TinyResearch research:records)
            {
                if(research.getSubjectPkId().equals(rcode))
                {
                    vpList =  com.alibaba.fastjson.JSONArray.parseArray(research.getVpInfo(),VpInfoVo.class);
                }
            }

            if(vpList==null||vpList.isEmpty())
            {
                return;
            }
            long experimnetSum = ExperimentMap.get(rcode);

            for(Testee testee:tList)
            {

                Map<String,Float> result = new HashMap<>();
                List<TesteeExperiment> testeeExperimentList= testeeExperimentService.list(new LambdaQueryWrapper<TesteeExperiment>().in(TesteeExperiment::getTesteeNo,testee.getId()));
                Map<String,Set<Integer>> record = testeeExperimentList.stream().collect(Collectors.groupingBy(TesteeExperiment::getVpCode,Collectors.mapping(TesteeExperiment::getExperimentId,Collectors.toSet())));
                //map<任务id，set<vp>>

                record.forEach((k,v)->{
                    float finishrate = (float)v.size()/experimnetSum;
                    result.put(k,finishrate);
                });
                Testee testee1 = new Testee();
                testee1.setFinishJson(ObjectUtil.toJson(result));
                testeeService.update(testee1,new LambdaQueryWrapper<Testee>().eq(Testee::getTesteeNo,testee.getTesteeNo()));

                if(testee.getType() == 0){
                    for (String key : result.keySet()) {
                        //这里要给受试者管理系统发送请求
                        log.info("回传数据！");
                        WebResponse<Research> res = researchManager.getBysubjectPkId(testee.getSubjectPkId());
                        JSONObject testeeBak = new JSONObject();
                        String mapperKey = testee.getSubjectCode() + "_" + key + "_1";
                        testeeBak.set("MAPPER_KEY",mapperKey);
                        testeeBak.set("SUBJECT_NAME",res.getData().getResearchName());
                        testeeBak.set("SITE_CODE",testee.getSiteCode());
                        testeeBak.set("INNER_CODE",testee.getTesteeNo());
                        testeeBak.set("SECTION_CODE",key);
                        for (VpInfoVo vp : vpList) {
                            if(key.equals(vp.getCode())){
                                testeeBak.set("SECTION_NAME",vp.getName());
                                break;
                            }
                        }
                        testeeBak.set("GATHERER","脑电管理系统");
                        Date now = new Date();
                        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String strDate = formatter.format(now);
                        testeeBak.set("GATHER_TIME",strDate);
                        testeeBak.set("SUBJECT_CODE",testee.getSubjectCode());
                        testeeBak.set("QC_SCORE","39b3381f990f47a1b3b4b0a4054b2d8b");
                        String percentage = String.valueOf(result.get(key) * 100);
                        testeeBak.set("PERCENTAGE",percentage);
                        testeeBak.set("FUN_TYPE",1);

//                    ArrayList<JSONObject> testeeBakList = null;
//                    testeeBakList.add(testeeBak);

                        String ybkJsonInfo = ObjectUtil.toJson(testeeBak);
                        Map<String, String> map = new HashMap<>();
                        try {
                            String encodedJson = URLEncoder.encode(ybkJsonInfo, "UTF-8");
                            encodedJson = "%5B" + encodedJson + "%5D";
                            map.put("json", encodedJson);
//                        String results = postMap("http://172.29.59.4:8080/SUBIMPAPI/SimpYbkController/saveYbkInfo",map);
                            String url = "http://172.29.59.4:8080/SUBIMPAPI/SimpYbkController/saveYbkInfo?json=" + encodedJson; // 测试
//                            String url = "http://172.29.59.3:8083/SUBIMPAPI/SimpYbkController/saveYbkInfo?json=" + encodedJson; // 正式
//                            String url = "http://localhost:18081/research/data/backRequest?json=" + encodedJson; // 本地

                            CloseableHttpClient httpClient = HttpClients.createDefault();
                            HttpPost post = new HttpPost(url);
                            CloseableHttpResponse responseBak = null;
                            String resultBak = null;
                            responseBak = httpClient.execute(post);
                            if (responseBak != null && responseBak.getStatusLine().getStatusCode() == 200) {
                                //获取response的body部分
                                HttpEntity entity = responseBak.getEntity();
                                //读取reponse的body部分并转化成字符串
                                resultBak = EntityUtils.toString(entity);
                            }
                            log.info(map.get("json"));
                            log.info(resultBak);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                            log.error("异常：", e);
                        } catch (ClientProtocolException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }
        });
    }

    public static String sendJsonPost(String url, String sendData) {
        String body = "";
        try {
            CloseableHttpClient client = HttpClients.createDefault();

            //创建post方式请求对象
            HttpPost httpPost = new HttpPost(url);

            //装填参数
            StringEntity s = new StringEntity(sendData, "UTF8");
            s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
            //设置参数到请求对象中
            httpPost.setEntity(s);
            //设置header信息
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

            //执行请求操作，并拿到结果（同步阻塞）
            HttpResponse response = client.execute(httpPost);
            //获取结果实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                body = EntityUtils.toString(entity, "UTF8");
            }
            EntityUtils.consume(entity);
            //为防止频繁调用一个接口导致接口爆掉，每次调用完成后停留100毫秒
            Thread.sleep(100);
        } catch (Exception e) {
            log.info("JSON数据发送失败，异常：{}", e.getMessage());
            log.error("异常：", e);
        }
        return body;
    }


//    public static String postMap(String url, Map<String, String> headerMap, Map<String, String> contentMap) {
     public static String postMap(String url, Map<String, String> contentMap) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        List<NameValuePair> content = new ArrayList<NameValuePair>();
        //将content生成entity
        Iterator iterator = contentMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, String> elem = (Entry<String, String>) iterator.next();
            content.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            //循环增加header
//            Iterator headerIterator = headerMap.entrySet().iterator();
//            while (headerIterator.hasNext()) {
//                Entry<String, String> elem = (Entry<String, String>) headerIterator.next();
//                post.addHeader(elem.getKey(), elem.getValue());
//            }
            if (content.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(content, "UTF-8");
                post.setEntity(entity);
            }
            //发送请求并接收返回数据
            response = httpClient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                result = EntityUtils.toString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
